/*
 * graph2D
 * Copyright (c) 2009 Shun Moriya <shun@mnu.sakura.ne.jp>
 *
 * The MIT License
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "particleManager.h"

namespace Graph2D
{
	ParticleManager::ParticleManager()
	{
	}

	ParticleManager::ParticleManager(const unsigned int hint)
	{
		activeParticleList = NULL;
		freeParticleList = NULL;

		for(unsigned int i = 0; i < hint; i++)
		{
			Particle* particle = new Particle();
			particle->setIndex(static_cast<unsigned short>(i));
			particle->setNext(freeParticleList);
			freeParticleList = particle;
		}
	}

	ParticleManager::~ParticleManager()
	{
		Particle* particle;

		particle = activeParticleList;
		while(particle)
		{
			Particle* next = particle->getNext();
//			particle->release();
			particle = next;
		}

		particle = freeParticleList;
		while(particle)
		{
			Particle* next = particle->getNext();
//			particle->release();
			particle = next;
		}
	}

	Particle* ParticleManager::popFreeParticle()
	{
		Particle* particle = freeParticleList;
		freeParticleList = particle->getNext();
		particle->setNext(NULL);
		return particle;
	}

	void ParticleManager::pushFreeParticle(Particle* particle)
	{
		particle->setNext(freeParticleList);
		freeParticleList = particle;
	}

	void ParticleManager::activate(Particle* particle)
	{
		particle->setNext(activeParticleList);
		activeParticleList = particle;
	}

	void ParticleManager::onUpdate(const UpdateInfomation& updateInfomation)
	{
		(void)updateInfomation;

		// 寿命がつきたパーティクルを回収します
		Particle** lastParticleLink = &activeParticleList;
		Particle* particle = activeParticleList;
		while(particle)
		{
			if(particle->getLife() <= 0.0f)
			{
				Particle* nextParticle = particle->getNext();

				particle->removeFromParent();

				*lastParticleLink = nextParticle;

				pushFreeParticle(particle);

				particle = nextParticle;
			}
			else
			{
				lastParticleLink = &particle->next;
				particle = particle->getNext();
			}
		}
	}
}
